package io.gitee.hechenl.easyopc.opcua;

import lombok.AllArgsConstructor;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UShort;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

@AllArgsConstructor
public class EasyNodeIdContext {

    private EasyNodeIdProvider easyNodeIdProvider;

    /**opc服务器ip和节点映射关系（可访问的节点）*/
    private final Map<String, List<NodeId>> accessNodeIdMap = new ConcurrentHashMap<>();
    /**opc服务器ip和节点映射关系（订阅的节点）*/
    private final Map<String, List<NodeId>> subNodeIdMap = new ConcurrentHashMap<>();

    @PostConstruct
    public void init() {
        // 可访问的节点
        List<EasyNodeId> accessNodeIdList = easyNodeIdProvider.getAccessNodeIdList();
        if (CollectionUtils.isEmpty(accessNodeIdList)) {
            throw new RuntimeException("OpcUaContext init No access nodes found");
        }
        for (EasyNodeId accessNodeId : accessNodeIdList) {
            accessNodeIdMap.put(accessNodeId.getServerIp(), accessNodeId.getNodeIds());
        }
        // 订阅的节点
        List<EasyNodeId> subscriptNodeIdList = easyNodeIdProvider.getSubscriptNodeIdList();
        if (!CollectionUtils.isEmpty(subscriptNodeIdList)) {
            for (EasyNodeId subscriptNodeId : subscriptNodeIdList) {
                subNodeIdMap.put(subscriptNodeId.getServerIp(), subscriptNodeId.getNodeIds());
            }
        }
    }

    public List<EasyNodeId> getAccessNodeIdList() {
        List<EasyNodeId> list = new ArrayList<>();
        for (Map.Entry<String, List<NodeId>> entry : accessNodeIdMap.entrySet()) {
            list.add(new EasyNodeId(entry.getKey(), entry.getValue()));
        }
        return list;
    }

    public List<EasyNodeId> getSubNodeIdList() {
        List<EasyNodeId> list = new ArrayList<>();
        for (Map.Entry<String, List<NodeId>> entry : subNodeIdMap.entrySet()) {
            list.add(new EasyNodeId(entry.getKey(), entry.getValue()));
        }
        return list;
    }

    /**获取节点所在的opc服务器ip*/
    public String getServerIP(Integer namespace, String identifier) {
        if (StringUtils.hasText(identifier)) {
            for (Map.Entry<String, List<NodeId>> entry : accessNodeIdMap.entrySet()) {
                if (entry.getValue().stream().anyMatch(nodeId ->
                                Objects.equals(UShort.valueOf(namespace), nodeId.getNamespaceIndex())
                                        && String.valueOf(nodeId.getIdentifier()).equals(identifier))) {
                    return entry.getKey();
                }
            }
        }
        return null;
    }

}
